<template>
  <div class="app-container">
    <div class="searchBox">
      <el-form label-position="right" label-width="150px" :model="search" ref="searchForm">
        <el-row>
          <el-col :span="8">
            <el-form-item label="事项类型：" prop="appCode">
              <el-select filterable v-model="search.appCode">
                <el-option
                  v-for="item in controlData.appOptions"
                  :key="item.appCode"
                  :label="item.appName"
                  :value="item.appCode"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="任务状态：" prop="taskStatus">
              <el-select v-model="search.taskStatus">
                <el-option
                  v-for="item in taskStatusOptions"
                  :key="item.value"
                  :label="item.key"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="预警状态：" prop="alertStatus">
              <el-select v-model="search.alertStatus">
                <el-option
                  v-for="item in alertStatusOptions"
                  :key="item.value"
                  :label="item.key"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="8">
            <el-form-item label="事项标题：" prop="instanceTitle">
              <el-input v-model="search.instanceTitle" placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="事项发起人：" prop="starterName">
              <el-input v-model="search.starterName" placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="任务处理人：" prop="assigneeName">
              <el-input v-model="search.assigneeName" placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="8">
            <el-form-item label="事项发起时间：" prop="instStartTime">
              <el-date-picker
                v-model="search.instStartTime"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择日期"
              ></el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="到：" prop="instEndTime">
              <el-date-picker
                v-model="search.instEndTime"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择日期"
              ></el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="环节名称：" prop="taskName">
              <el-input v-model="search.taskName" placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="8">
            <el-form-item label="任务接收时间：" prop="startTime">
              <el-date-picker
                v-model="search.startTime"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择日期"
              ></el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="到：" prop="endTime">
              <el-date-picker
                v-model="search.endTime"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择日期"
              ></el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8"></el-col>
        </el-row>

        <el-row>
          <el-col :span="8">
            <el-form-item label="办理完成时间：" prop="startFinishTime">
              <el-date-picker
                v-model="search.startFinishTime"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择日期"
              ></el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="到：" prop="endFinishTime">
              <el-date-picker
                v-model="search.endFinishTime"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择日期"
              ></el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item style="margin-top: -2px">
              <el-button type="primary" @click="searchQuery">查询</el-button>
              <el-button type="info" @click="search = {};searchQuery()">重置</el-button>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>

    <qm-table
      ref="qmTable"
      :data="query"
      keyProp="taskId"
      :showOrder="false"
      :showCheckbox="false"
      :showDelete="false"
      :showView="false"
      menuType="text"
      :showAdd="false"
      :showEdit="false"
      :showExport="true"
      :formOptions="{ labelWidth: '120px' }"
      :menuOptions="{ width: 120 }"
      :rules="rules"
    >
      <qm-table-column field="instanceTitle">事项标题</qm-table-column>
      <qm-table-column field="starterName">事项发起人</qm-table-column>
      <qm-table-column field="instStartTime" fieldType="datetime" width="150px">事项发起时间</qm-table-column>
      <qm-table-column field="instStatus">事项状态</qm-table-column>
      <qm-table-column field="taskName">当前环节</qm-table-column>
      <qm-table-column field="startTime">任务接收时间</qm-table-column>
      <qm-table-column field="assigneeName">任务处理人</qm-table-column>
      <qm-table-column field="finishTime" fieldType="datetime" width="150px">办理完成时间</qm-table-column>
      <qm-table-column field="alertStatus" width="100px" align="center">
        预警状态
        <template v-slot:content="{ row }">
          <span>
            <template v-if="row.alertStatus === 'redLevel'">
              <i class="fa fa-circle red" title="超时告警"></i>
            </template>
            <template v-else-if="row.alertStatus === 'yellowLevel'">
              <i class="fa fa-circle yellow" title="超时提醒"></i>
            </template>
            <template v-else>
              <i class="fa fa-circle green" title="正常"></i>
            </template>
          </span>
        </template>
      </qm-table-column>
      <qm-table-column
        field="taskStatus"
        fieldtype="enum"
        :enumOptions="[
          { key: '完成', value: 'finished' },
          { key: '处理中', value: 'processing' },
        ]"
      >任务状态</qm-table-column>
      <template v-slot:toolbar>
        <el-button type="primary" @click="showEditAgent">修改待办人</el-button>
      </template>
      <template v-slot:moreBtn="{ row }">
        <el-button type="text" @click="details(row)">详情</el-button>
        <el-button type="text" @click="toHistory(row)">历史</el-button>
        <el-dropdown v-if="row.taskStatus != 'finished'">
          <el-button style="padding-left: 7px;" size="mini" type="text">更多</el-button>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item @click.native="activate(row)" v-if="row.taskStatus == 'pausing'">激活</el-dropdown-item>
            <el-dropdown-item @click.native="suspend(row)" v-else>挂起</el-dropdown-item>
            <el-dropdown-item @click.native="terminate(row)">终止</el-dropdown-item>
            <el-dropdown-item @click.native="rollback(row)">撤回上个环节</el-dropdown-item>
            <el-dropdown-item @click.native="jump(row)">撤回到指定环节</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </template>
    </qm-table>
    <el-dialog
      title="查看历史"
      :visible.sync="historyVisible"
      @closed="historyVisibleClose"
      width="80%"
    >
      <el-row>
        <el-col :span="3">
          <el-button type="primary" @click="addAssignee" icon="el-icon-plus">新增代办人</el-button>
        </el-col>
      </el-row>
      <el-table :data="historyList" style="width: 100%">
        <el-table-column label="环节名称" width="180">
          <template slot-scope="scope">
            <el-input type="text" v-model="scope.row.taskName" disabled />
          </template>
        </el-table-column>
        <el-table-column label="发送人" width="180">
          <template slot-scope="scope">
            <el-input type="text" v-model="scope.row.senderName" disabled />
          </template>
        </el-table-column>
        <el-table-column label="接受人" width="180">
          <template slot-scope="scope">
            <el-input
              v-if="scope.row.finishTime"
              type="text"
              v-model="scope.row.assigneeName"
              disabled
            />
            <!-- <el-select v-else v-model="scope.row.assigneeName" :change="setAssigneeName(scope.row)">
              <el-option
                v-for="item in assigneeList"
                :key="item.userName"
                :label="item.userName"
                :value="item.userName"
              ></el-option>
            </el-select>-->
            <el-select
              v-else
              v-model="scope.row.assigneeName"
              value-key="value"
              filterable
              remote
              placeholder="请输入关键词"
              :remote-method="remoteMethod"
            >
              <el-option
                v-for="item in editAgent.users"
                :key="item.userName"
                :label="`${item.userName}（${item.loginId}）`"
                :value="item.userName"
              ></el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="处理人" width="180">
          <template slot-scope="scope">
            <el-input type="text" v-model="scope.row.handlerName" disabled />
          </template>
        </el-table-column>
        <el-table-column label="接收时间" width="180">
          <template slot-scope="scope">
            <el-input type="text" v-model="scope.row.startTime" disabled />
          </template>
        </el-table-column>
        <el-table-column label="处理时间" width="180">
          <template slot-scope="scope">
            <el-input type="text" v-model="scope.row.finishTime" disabled />
          </template>
        </el-table-column>
        <el-table-column label="审批意见" width="180">
          <template slot-scope="scope">
            <el-input type="text" v-model="scope.row.opinionText" disabled />
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button
              v-if="!scope.row.finishTime"
              type="danger"
              icon="el-icon-delete"
              size="mini"
              @click="removeColumn(scope.row)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="historySave">提 交</el-button>
        <el-button @click="historyVisible = false">关 闭</el-button>
      </span>
    </el-dialog>

    <vxe-modal v-model="editAgent.visible" title="修改待办人" show-footer>
      <el-form style="padding: 12px;">
        <el-form-item label="应用名称：">
          <el-select v-model="editAgent.appCode" placeholder="请选择">
            <el-option
              v-for="(item,index) in editAgent.actExtAppList"
              :key="index"
              :label="item.appName"
              :value="item.appCode"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="当前操作类型：">
          <el-select v-model="editAgent.operateType" placeholder="请选择">
            <el-option
              v-for="item in editAgent.operate"
              :key="item.index"
              :label="item.type"
              :value="item.index"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="环节名称：">
          <el-select v-model="editAgent.taskActorId" placeholder="请选择">
            <el-option
              v-for="(item,index) in editAgent.taskActorIdList"
              :key="index"
              :label="item.taskName"
              :value="item.taskActorId"
            ></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="代办人：">
          <el-select
            v-model="editAgent.assigneeId"
            value-key="value"
            multiple
            filterable
            remote
            placeholder="请输入关键词"
            :remote-method="remoteMethod"
          >
            <el-option
              v-for="item in editAgent.users"
              :key="item.userId"
              :label="item.userName"
              :value="item.userId"
            ></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="选择新的代办人：" v-if="editAgent.isReplace">
          <el-select v-model="editAgent.newAssigneeId" placeholder="请选择">
            <el-option
              v-for="(item,index) in editAgent.assigneeList"
              :key="index"
              :label="item.userName"
              :value="item.userId"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button type="primary" @click="agentSave">提 交</el-button>
        <el-button @click="editAgent.visible = false">关 闭</el-button>
      </template>
    </vxe-modal>
  </div>
</template>

<script>
import Controller from "@/libs/framework/controller";
import request from "@/utils/request";
import _ from "lodash";
export default class Instance extends Controller {
  onBeforeInit() {
    this.urls = {
      query: [{ url: "/workflow/monitor/query", method: "post" }],
      save: "/workflow/monitor/save",
      delete: "/workflow/monitor/delete",
      entity: "/workflow/monitor/getEntity",
    };
    this.urls.model = "/workflow/monitor/getListModel";
  }

  mixin() {
    return {
      data() {
        return {
          assigneeList: [],
          historyVisible: false,
          historyList: null,
          workItem: [],
          rules: {},
          taskStatusOptions: [
            { key: "处理中", value: "processing" },
            { key: "已完成", value: "finished" },
            {
              key: "已终止",
              value: "terminated",
            },
          ],
          alertStatusOptions: [
            { key: "黄灯预警", value: "yellowLevel" },
            { key: "红灯告警", value: "redLevel" },
          ],

          editAgent: {
            visible: false,
            users: [],
            actExtAppList: [],
            taskActorIdList: [],
            assigneeList: [],
            operate: [
              { index: 1, type: "批量删除指定待办人" },
              { index: 2, type: "批量添加待办人" },
              { index: 3, type: "批量替换待办人" },
            ],
            operateType: null,
            isReplace: false,
            appCode: null,
            appName: null,
            taskActorId: null,
            assigneeId: null,
            newAssigneeId: null,
          },
        };
      },
      watch: {
        "editAgent.appCode": function (code) {
          for (let item of this.editAgent.actExtAppList) {
            if (item.appCode == code) {
              this.editAgent.appName = item.appName;
              this.editAgent.taskActorId = null;
            }
          }
          request({
            url: "/workflow/monitor/getStepName",
            method: "post",
            data: { appCode: this.editAgent.appCode },
          })
            .then((r) => {
              this.editAgent.taskActorIdList = r || [];
            })
            .catch((r) => {
              this.notifyError((r || {}).message || "请求失败，请稍后再试");
            });
        },
        "editAgent.operateType": function (key) {
          this.editAgent.isReplace = key < 3;
        },
        "editAgent.taskActorId": function (taskActorId) {
          for (let item of this.editAgent.taskActorIdList) {
            if (item.taskActorId == taskActorId) {
              request({
                url: "/workflow/monitor/getAssingnee",
                method: "post",
                data: {
                  definitionId: item.definitionId,
                  taskName: item.taskName,
                },
              })
                .then((r) => {
                  this.editAgent.assigneeList = r || [];
                  this.editAgent.assigneeId = null;
                })
                .catch((r) => {
                  this.notifyError((r || {}).message || "请求失败，请稍后再试");
                });
            }
          }
        },
      },
      methods: {
        historySave() {
          let items = [];
          for (let item of this.historyList) {
            if (!item.finishTime) {
              items.push(item);
            }
          }
          for (let i = 0; i < items.length; i++) {
            for (let j = i + 1; j < items.length; j++) {
              if (items[i].assigneeId == items[j].assigneeId) {
                this.$message({
                  type: "info",
                  message: "存在重复数据，请检查确认",
                });
                return;
              }
            }
          }
          request({
            url: "/workflow/monitor/historySave2",
            method: "post",
            data: {
              items: items,
            },
          })
            .then((r) => {
              if (r && !r.initMessage) {
                this.$message({
                  message: "保存成功",
                  type: "success",
                });
                this.$refs["qmTable"].refresh();
              } else {
                reject(r.initMessage || "数据请求失败");
              }
            })
            .catch((e) => {
              reject(e);
            });
        },
        removeColumn(item) {
          this.$confirm("确定要删除此列吗？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              for (let i = 0; i < this.historyList.length; i++) {
                if (this.historyList[i].taskId == item.taskId) {
                  this.historyList.splice(i, 1);
                }
              }
            })
            .catch(() => {
              this.$message({
                type: "info",
                message: "已取消删除",
              });
            });
        },
        setAssigneeName(r) {
          if (this.assigneeList) {
            for (let item of this.assigneeList) {
              if (r.assigneeName == item.userName) {
                r.assigneeId = item.userId;
                r.assigneeDeptId = item.departmentId;
                r.assigneeDeptName = item.departmentName;
                return;
              }
            }
          }
        },
        addAssignee() {
          let items = [];
          for (let item of this.historyList) {
            if (item.taskStatus != "finished") {
              items.push(item);
            }
          }
          if (items.length > 0) {
            this.workItem = items[0];
            this.historyList.push(
              _.extend({}, this.workItem, {
                assigneeId: null,
                assigneeName: null,
                assigneeDeptId: null,
                assigneeDeptName: null,
              })
            );
          } else {
            this.$message("暂无待办，无法添加!");
            return;
          }
        },
        historyVisibleClose() {
          this.assigneeList = [];
          this.historyVisible = false;
          this.historyList = null;
          this.workItem = [];
        },
        toHistory(data) {
          this.historyVisible = true;
          request({
            url: "/workflow/monitor/getHistory",
            method: "get",
            params: {
              taskId: data.taskId,
              assigneeId: data.assigneeId,
              status: data.taskStatus,
            },
          })
            .then((r) => {
              if (r && !r.initMessage) {
                this.historyList = r.history;
                this.workItem = r.workItem;
              } else {
                this.msgError(r.initMessage || "数据请求失败");
              }
            })
            .catch((e) => {
              this.msgError((e || {}).initMessage || "数据请求失败");
            });
        },
        details(row) {
          let action =
            row.taskStatus === "processing" ? "processEdit" : "processView";
          let name =
            row.taskStatus === "processing" ? "taskId" : "historyTaskId";
          this.getWorkflowArgs({ taskId: row.taskId }).then((rlt) => {
            if (rlt && rlt.appUrl && rlt.appCode) {
              window.open(
                `${rlt.appUrl}?action=${action}&${name}=${
                  row.taskId
                }&assigneeId=${row.assigneeId}&appCode=${rlt.appCode}&version=${
                  rlt.version
                }&_r=${new Date().getTime()}`
              );
            } else {
              this.notifyError("无法获取应用的处理地址");
            }
          });
        },
        showEditAgent() {
          this.initData();
        },
        initData: function () {
          request({
            url: "/workflow/monitor/initData",
            method: "get",
          })
            .then((r) => {
              this.editAgent.actExtAppList = (r || {}).actExtAppList || [];
              this.editAgent.visible = true;
            })
            .catch((r) => {
              this.editAgent.visible = false;
              this.notifyError((r || {}).message || "请求失败，请稍后再试");
            });
        },
        remoteMethod: function (query) {
          request({
            url: "/admin/sysRole/setUsers/userSelect2",
            method: "get",
            params: { term: query },
          }).then((r) => {
            this.editAgent.users = r.data;
          });
        },
        agentSave: function () {
          let assigneeIds = [];
          if (
            this.editAgent.assigneeId &&
            this.editAgent.assigneeId.length > 0
          ) {
            for (item of this.editAgent.assigneeId) {
              assigneeIds.push(item.value);
            }
          }

          request({
            url: "/workflow/monitor/agentSave",
            method: "post",
            data: {
              taskActorId: this.editAgent.taskActorId,
              assigneeIds: assigneeIds,
              newAssigneeId: this.editAgent.newAssigneeId,
              operateType: this.editAgent.operateType,
            },
          })
            .then((r) => {
              if (r && r.success) {
                this.notifySuccess("保存成功");
              }
            })
            .catch((r) => {
              this.notifyError((r || {}).message || "请求失败，请稍后再试");
            });
        },
        suspend(r) {
          this.$confirm("确定要挂起吗？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              var url = getAppUrl(r.appCode, r.appVersion, r.taskId);
              url = url + "processSuspend";
              url = url + "?pageAction=view&appCode=" + r.appCode;
              url = url + "&version=" + r.appVersion;
              url = url + "&historyTaskId=" + r.taskId;
              url = url + "&assigneeId=" + r.assigneeId;
              $.post(url, { instanceId: r.instanceId }, function (a) {
                if (a && a.success) {
                  bootbox.toastr("挂起成功");
                  page.search();
                } else {
                  bootbox.alert(a.message || "挂起失败");
                }
              });
            })
            .catch(() => {
              this.$message({
                type: "info",
                message: "用户取消操作",
              });
            });
        },
        activate(r) {
          this.$confirm("确定要挂起吗？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              var url = getAppUrl(r.appCode, r.appVersion, r.taskId);
              url = url + "processActivate";
              url = url + "?pageAction=view&appCode=" + r.appCode;
              url = url + "&version=" + r.appVersion;
              url = url + "&historyTaskId=" + r.taskId;
              url = url + "&assigneeId=" + r.assigneeId;
              $.post(url, { instanceId: r.instanceId }, function (a) {
                if (a && a.success) {
                  bootbox.toastr("激活成功");
                  page.search();
                } else {
                  bootbox.alert(a.message || "激活失败");
                }
              });
            })
            .catch(() => {
              this.$message({
                type: "info",
                message: "用户取消操作",
              });
            });
        },
        terminate(r) {
          this.$confirm("确定要终止吗？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              var url = getAppUrl(r.appCode, r.appVersion, r.taskId);
              url = url + "processTerminate";
              url = url + "?pageAction=view&appCode=" + r.appCode;
              url = url + "&version=" + r.appVersion;
              url = url + "&historyTaskId=" + r.taskId;
              url = url + "&assigneeId=" + r.assigneeId;
              $.post(url, { instanceId: r.instanceId }, function (a) {
                if (a && a.success) {
                  bootbox.toastr("终止成功");
                  page.search();
                } else {
                  bootbox.alert(a.message || "终止失败");
                }
              });
            })
            .catch(() => {
              this.$message({
                type: "info",
                message: "用户取消操作",
              });
            });
        },
        rollback(r) {
          this.$confirm("确定要撤回此事项码？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              App.blockUI($(document.body));
              var url = getAppUrl(r.appCode, r.appVersion, r.taskId);
              url = url + "processRollback";
              url = url + "?pageAction=view&appCode=" + r.appCode;
              url = url + "&historyTaskId=" + r.prevTaskId;
              url = url + "&assigneeId=" + r.senderId;
              url = page.util.appendPrimaryKey(url, data.primaryKey);
              $.post(url, null, function (r) {
                App.unblockUI($(document.body));
                if (r && r.success === true) {
                  bootbox.toastr("撤回成功");
                  page.search();
                } else {
                  bootbox.alert(r.message || "撤回失败");
                }
              }).error(function (r) {
                bootbox.toastr("撤回失败！", r.message);
                App.unblockUI($(document.body));
              });
            })
            .catch(() => {
              this.$message({
                type: "info",
                message: "用户取消操作",
              });
            });
        },
        jump(r) {
          var commonUrl = "";
          commonUrl = commonUrl + "?pageAction=edit&appCode=" + r.appCode;
          commonUrl = commonUrl + "&version=" + r.appVersion;
          commonUrl = commonUrl + "&taskId=" + r.taskId;
          commonUrl = commonUrl + "&assigneeId=" + r.assigneeId;
          var url = getAppUrl(r.appCode, r.appVersion, r.taskId);
          $.open(
            url + "jumpTask" + commonUrl,
            function (rlt) {
              if (rlt) {
                App.blockUI($(document.body));
                // url = url +"processJump"
                url = url + "processRollbackAssign";
                url = url + commonUrl;
                url = page.util.appendPrimaryKey(url, data.primaryKey);
                $.post(url, { taskId: r.taskId }, function (r) {
                  App.unblockUI($(document.body));
                  if (r && r.success === true) {
                    bootbox.toastr("撤回成功");
                    page.search();
                  } else {
                    bootbox.alert(r.message || "撤回失败");
                  }
                }).error(function (r) {
                  bootbox.toastr("跳转失败！", r.message);
                  App.unblockUI($(document.body));
                });
              }
            },
            { instanceId: r.instanceId, title: "选择撤回环节" }
          );
        },
      },
    };
  }
}
</script>

<style scoped lang="scss">
.fa-circle {
  font-size: large;
}

.fa-circle.red {
  color: red;
}

.fa-circle.yellow {
  color: orange;
}

.fa-circle.green {
  color: green;
}
</style>

